package correctness;

import static org.junit.Assert.*;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import model.LogicType;
import model.editormodel.EditorModel;

import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import view.UtilityConstants;
import controller.commoncontroller.UtilityDialogs;

/**
 * <b> Mit dieser Testklasse wird Folgendes getestet:</b> <br>
 * <br>
 * Es soll eine Schaltung erzeugt werden, die als selbstdefiniertes Bauteil
 * exportiert und anschliessend in einer neuen Schaltung als Bauteil eingefuegt
 * wird.
 */
public class ExportAndInsertSelfdefinedTest {
	

	// Objekte die benoetigt werden
	private static EditorModel eModel;

	// Name der Schaltung, die geladen werden soll
	private static String name = "exportAndInsertSelfdefined";
	private static String sdname = name + "_JUNIT";
	private static String location;
	private static File xmlFile;

	// speichern der Elementanzahlen
	Map<LogicType, Integer> numberOfTypes = new HashMap<LogicType, Integer>();

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		eModel = new EditorModel();

		// Pfad der zu ladenden Schaltung
		location = "test" + UtilityConstants.SEPARATOR + "model"
				+ UtilityConstants.SEPARATOR + "editormodel"
				+ UtilityConstants.SEPARATOR + "test_saved_circuits"
				+ UtilityConstants.SEPARATOR + name
				+ UtilityDialogs.XML_EXTENSION;
		xmlFile = new File(UtilityConstants.SD_DIRECTORY + sdname
				+ UtilityDialogs.XML_EXTENSION);
	}

	@Before
	public void setUp() throws Exception {
		// Einlesen der vorbereiteten Schaltung
				assertTrue("Die Schaltung konnte nicht gelesen werden",
						eModel.loadCircuit(location));
	}

	@Test
	public void exportTest() {
		// Einlesen der vorbereiteten Schaltung
		assertTrue("Die Schaltung konnte nicht gelesen werden",
				eModel.loadCircuit(location));

		// Zuerst muss sichergestellt werden, dass das selbstdefinierte Bauteil
		// nicht schon bereits existiert
		if (xmlFile.exists()) {
			xmlFile.delete();
		}
		// Exportieren der Schaltung
		assertTrue(
				"Schaltung konnte nicht exportiert werden",
				eModel.exportComponent(sdname) == EditorModel.SaveCircuitResponse.SAVE_OK);
		// Versucht man diese erneut zu speichern, darf dies nicht möglich sein,
		// da der Name ja bereits vergeben wurde
		assertTrue(
				"Schaltung konnte exportiert werden obwohl der Name bereits vorhanden ist",
				eModel.exportComponent(sdname) == EditorModel.SaveCircuitResponse.NAME_ALREADY_DEFINED);
		eModel.newCircuit();
		// Es darf nicht möglich sein eine leere Schaltung zu exportieren
		assertTrue(
				"Leere Schaltung konnte exportiert werden",
				eModel.exportComponent(sdname) == EditorModel.SaveCircuitResponse.SOME_CHECK_FAILED);
	}

	@Test
	public void importTest() {
		// speichern der Anzahl der Elemente
		numberOfTypes = eModel.getCircuitModel().getNumberOfEachLogicType();
		assertFalse(
				"Eine nicht vorhandene Komponente darf nicht geladen werden",
				eModel.importComponent("gibts_hoffentlich_ned"));
		assertTrue(
				"Laden des zuvor exportierten Bauteils ist nicht möglich",
				eModel.importComponent(UtilityConstants.SD_DIRECTORY
						+ UtilityConstants.SEPARATOR + sdname));
		// Die Anzahl der Elemente von jedem Type müssen natürlich mit dem der
		// Ursprungsschaltung übereinstimmen
		boolean isEqual = true;
		for (Entry<LogicType, Integer> e : eModel.getCircuitModel().getNumberOfEachLogicType()
				.entrySet()) {
			if (e.getValue() != numberOfTypes.get(e.getKey())) {
				isEqual = false;
				break;
			}
		}
		assertTrue("Es gibt Abweichungen von der Ursprungsschaltung", isEqual);
	}
}
